package com.rongkang.interview.juc.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @Description: 实现一个自旋锁
 * <p>
 * 优点：循环到成功为止，相当于wait
 * 缺点：一直循环占用cpu资源
 * @author: 荣康
 * @date: 2021/12/6
 */
public class SpinLockDemo {
    volatile AtomicReference<Thread> atomicReference = new AtomicReference<>();

    public static void main(String[] args) {

        SpinLockDemo spinLockDemo = new SpinLockDemo();
        new Thread(() -> {
            //开始占有锁
            spinLockDemo.lock();
            try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); }
            //释放锁
            spinLockDemo.unlock();
        }, "t1").start();
        //主线程等待一秒，确保t1先执行
        try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
        new Thread(() -> {
            spinLockDemo.lock();
            spinLockDemo.unlock();
        }, "t2").start();
    }
    //第一次进来肯定为null，先进行上锁，如果第一次进来不是null，那就进行自旋
    public void lock() {
        //获取到当前线程
        Thread thread = Thread.currentThread();
        System.out.println(Thread.currentThread().getName() + "\t 进入");
        //第一次进来，如果是null，那么就将它替换成当前线程，如果进来不是null，就自旋
        while (!atomicReference.compareAndSet(null, thread)) {

        }
    }
    public void unlock() {
        //获取到当前线程
        Thread thread = Thread.currentThread();
        while (! atomicReference.compareAndSet(thread, null)) {

        }
        System.out.println(Thread.currentThread().getName() + "\t invoke 释放锁");
    }

}

